﻿<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
  <head>
	<meta charset="utf-8">
    <title>My JSP 'parallelCoordinate.jsp' starting page</title>
	<script src="../js/d3.v3.min.js"></script>

  <link rel="stylesheet" href="../parallelCoordinate/css/d3.parallelcoordinate.css" type="text/css"></link>
 
<style>
#chartPanel {
	float: left;
}
#controlPanel {
	position: absolute;
	right: 10px;
	top: 10px;
	width: 260px;
}
.legend {
	font-size: 20px;
}
</style>
  <s:head/>
  </head>

  <body>
  
  <div id="chartPanel"></div>
  <div id="controlPanel">
  	
  	<form action="<s:url action="fileUpload" namespace="/parallelcoord"/>" method="post" enctype="multipart/form-data">
  		<input type="hidden" name="destPage" value="<%= request.getServletPath()%>" />
  		<div>
  			<label for="dataFile">csv file</label>
  			<s:file name="data" />
  		</div>
  		<div>
  			<input type="submit"/>
  		</div>
  	</form>
  </div>
  
 <script>
 	var margin = {top: 20, right: 20, bottom: 80, left: 40},
 		width = 860,
 		height = 600;
 	var dimensions = []; // 通过对导入的csv文件分析得出属性维数
 	var axis = d3.svg.axis().orient("left"); // 每个属性对应一个坐标轴
 	var foreground; // 显示的数据项
 	var line = d3.svg.line(); // 确定每一个数据项对应path元素的d属性
 	var gAttrbutes; // 每个属性对应一个坐标轴.包含g的selection
 	var dragIndex; // 当前被拖拽的坐标轴
 	var clusters = [];
 	
 	var x = d3.scale.ordinal().rangePoints([0, width], 1); // 根据维数平分宽度得到坐标系x方向上的位置
 	var y = {}; // 根据属性数值的分布规格化后得到的对应y轴的映射
 	
 	var color = d3.scale.category10(); // 不同cluster使用不同颜色显示
 	
 	var container = d3.select("#chartPanel").append("svg")
		.attr("width", width + margin.left + margin.right)
		.attr("height", height + margin.top + margin.bottom)
		.append("g")
		.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
 	
 	d3.csv('<s:property value="#session['CURRENT_FILE']"/>', function (data){
 		
 		// 选一个数据项确定属性个数
 		dimensions = d3.keys(data[0]).filter(function (d){
 			return d != "cluster";
 		});
 		
 		x.domain(dimensions);
 		
 		data.forEach(function (d) {
 			var c = d["cluster"];
 			if (clusters.indexOf(c) == -1)
 			{
 				clusters.push(c);
 			} // end if
 		});

 		dimensions.forEach(function(attrName){
 			
 			data.forEach(function(d){
 				d[attrName] = +d[attrName];
 			});
 			
 			// 确定每一个属性值的上下限.用于确定比例尺
 			y[attrName] = d3.scale.linear()
 				.domain(d3.extent(data, function(d){ return d[attrName]}))
 				.range([height, 0]);
 			
 			y[attrName].brush = d3.svg.brush()
 				.y(y[attrName])
 				.on("brush", brush);
 		});
 		
 		foreground = container.append("g")
 			.attr("class", "foreground")
 			.selectAll("path")
 			.data(data)
 			.enter().append("path")
 			.attr("d", path)
 			.attr("class", function(d){ return d.cluster; })
 			.style("stroke", function(d){ return color(d.cluster); });
 			
 		gAttributes = container.selectAll(".attr")
 			.data(dimensions)
 			.enter().append("g")
 			.attr("class", "attr")
 			.attr("transform", function(d){ return "translate(" + x(d) + ")"; })
 			.call(d3.behavior.drag()
 					.origin(function(d) { return {x: x(d)}; })
 					.on("dragstart", dragstart)
 					.on("drag", drag)
 					.on("dragend", dragend)
 				);
 		gAttributes.append("g")
 			.attr("class", "axis")
 			.each(function(d) {
 				d3.select(this).call(axis.scale(y[d]));
 			}).append("text")
 			.attr("text-anchor", "middle")
 			.attr("y", -9)
 			.text(String);
 		
 		gAttributes.append("g")
 			.attr("class", "brush")
 			.each(function(d) { d3.select(this).call(y[d].brush); })
 			.selectAll("rect")
 			.attr("x", -8)
 			.attr("width", 16);
 		
		var legend = container.selectAll("g.legend")
						.data(clusters)
						.enter().append("g")
						.attr("class", "legend")
						.attr("transform", function (d, i) {
							return "translate(0," +( height + i * 20) +")";
						});
		legend.append("line")
				.attr("stroke", function (d) { return color(d); })
				.attr("x2", 14);
						
 		legend.append("text")
 				.attr("x", 16)
 				.attr("dy", ".31em")
 				.text(String);
		
 		function dragstart(d)
 		{
 			dragIndex = dimensions.indexOf(d);
 		}
 		function drag(d)
 		{
 			x.range()[dragIndex] = d3.event.x;
 			dimensions.sort(function(a, b) { return x(a) - x(b); });
 			gAttributes.attr("transform", function(d) {
 				return "translate(" + x(d) + ")";
 				});
 			foreground.attr("d", path);
 		}
 		function dragend(d)
 		{
 			x.domain(dimensions).rangePoints([0, width], 1);
 			var t = d3.transition().duration(500);
 			t.selectAll(".attr").attr("transform", function(d) {
 				return "translate(" + x(d) + ")";
 			});
 			t.selectAll(".foreground path").attr("d", path);
 		}
 		
 	});
 	
 	function path(d)
 	{
 		return line(dimensions.map(function (attrName){ 
 			return [x(attrName), y[attrName](d[attrName])]; 
 			}));
 	}
 	
 	function brush()
 	{
 		var actives = dimensions.filter(function(p) { return !y[p].brush.empty(); }),
 			extents = actives.map(function(p) { return y[p].brush.extent(); });
 		foreground.classed("fade", function(d) {
 			return !actives.every(function(p, i) {
 				return extents[i][0] <= d[p] && d[p] <= extents[i][1];
 			});
 		});
 		
 	}
 	
 </script>
  
  
  </body>
</html>



















